///////////////////////////////////
// 
//  TestDotLocate.cpp
//
//  Wiicussion
//  HCI 575 Class project
//  Spring 2007
// 
//  Authors:  Jeremy Bennett
//            Adam Faeth
//            Michael Oren
//
///////////////////////////////////////////////////////////


// NOTE:  Be sure to define _TEST_DOT_LOCATE_ if you plan to run the tests
// on DotLocate by themselves (it will then include main() )

#include "stdafx.h"
#include "DotLocate.h"
#include <iostream>

#define MAXHEIGHT 300
#define MAXDIST 150
#define PIXTOCM 10

class TestDotLocate
{
  public:
    // Constructor/destructor
    TestDotLocate(void) 
    {
        // Max height, Max dist, pixels to cm
        _ltr = new DotLocate(MAXHEIGHT, MAXDIST, PIXTOCM);
    }
    ~TestDotLocate(void)
    {
        delete _ltr;
    }
    
    ///////////////////////////////////
    // Test Suite:
    bool testAll(void)
    {
        bool bRes = true;
        
        // Run test suite
        bRes &= testBoundaryXAxis();
        bRes &= testBoundaryYAxis();
        bRes &= testBoundaryZAxis();
        //bRes &= testBoundaryCenter();
        return bRes;
        
        // TODO: Create a function that builds a test from left side, right side, top, bottom and center
    }
    
    
    ///////////////////////////////////
    // Boundary tests on the X-Axis
    bool testBoundaryXAxis(void)
    {
        bool bRes = true;
        float fCenter = MAXHEIGHT/2.0f;
        float fBgSide = MAXHEIGHT/5.0f;
        float fSmSide = MAXHEIGHT/10.0f;
        std::cout << "\n************************\n"
                  <<   "**    X-Axis Tests    **\n"
                  <<   "************************" << std::endl;
        
        
        // Farthest position to the left
        // Class:     Boundary.XAxis
        // Test:      001
        // Position:  Farthest Left
        // Point At:  center
        std::cout << "Farthest Left (leftside max, right side min):" << std::endl;
        _testDotLocate(0.0f, 0.0f,
                       MAXHEIGHT-1.0f, fCenter-0.5f,
                       MAXHEIGHT-1.0f, fCenter+0.5f,
                       0.0f, 0.0f);  
                       
        // Farthest position to the right
        // Class:     Boundary.XAxis
        // Test:      002
        // Position:  Farthest Right
        // Point At:  center
        std::cout << "Farthest Right (leftside min, right side max):" << std::endl;
        _testDotLocate(0.0f, fCenter-0.5f,
                       MAXHEIGHT-1.0f, 0.0f,
                       MAXHEIGHT-1.0f, MAXHEIGHT-1.0f,
                       0.0f, fCenter+0.5f);
             
                       
        // Note:
        // Centered is the same for all, so test once in the z-axis tests
        
        // Pointing left from the left side
        // Class:     Boundary.XAxis
        // Test:      003
        // Position:  Left
        // Point At:  Left
        std::cout << "Positioned Left, Pointing left:" << std::endl;
        _testDotLocate(640.0f-fBgSide, fCenter-fBgSide,
                       640.0f, fCenter-fSmSide,
                       640.0f, fCenter+fSmSide,
                       640.0f-fBgSide, fCenter+fBgSide);
                       
        // Pointing right from the left side
        // Class:     Boundary.XAxis
        // Test:      004
        // Position:  Left
        // Point At:  Right
        std::cout << "Positioned Left, Pointing Right:" << std::endl;   
        _testDotLocate(0.0f, fCenter-fBgSide,
                       fBgSide, fCenter-fSmSide,
                       fBgSide, fCenter+fSmSide,
                       0.0f, fCenter+fBgSide);                 
        
        // Pointing Up from the left side
        // Class:     Boundary.XAxis
        // Test:      005
        // Position:  Left
        // Point At:  Up
        std::cout << "Positioned Left, Pointing Up:" << std::endl;   
        _testDotLocate(fCenter-fBgSide, 0.0f,
                       fCenter+fBgSide, fSmSide,
                       fCenter+fBgSide, fBgSide,
                       fCenter-fBgSide, 0.0f);    
                       
        // Pointing down from the left side
        // Class:     Boundary.XAxis
        // Test:      006
        // Position:  Left
        // Point At:  Down
        std::cout << "Positioned Left, Pointing Down:" << std::endl;   
        _testDotLocate(fCenter-fBgSide, 480.0f - fSmSide,
                       fCenter+fSmSide, 480.0f,
                       fCenter+fBgSide, 480.0f,
                       fCenter-fBgSide, 480.0f - fSmSide);  
                       
                       
                       
        // Pointing left from the right side
        // Class:     Boundary.XAxis
        // Test:      007
        // Position:  Right
        // Point At:  Left
        std::cout << "Positioned Right, Pointing left:" << std::endl;
        _testDotLocate(640.0f-fBgSide, fCenter-fSmSide,
                       640.0f, fCenter-fBgSide,
                       640.0f, fCenter+fBgSide,
                       640.0f-fBgSide, fCenter+fSmSide);
        
        // Pointing right from the right side
        // Class:     Boundary.XAxis
        // Test:      008
        // Position:  Right
        // Point At:  Right
        std::cout << "Positioned Right, Pointing Right:" << std::endl;   
        _testDotLocate(0.0f, fCenter-fSmSide,
                       fBgSide, fCenter-fBgSide,
                       fBgSide, fCenter+fBgSide,
                       0.0f, fCenter+fSmSide);                 
        
        // Pointing Up from the right side
        // Class:     Boundary.XAxis
        // Test:      009
        // Position:  Right
        // Point At:  Up
        std::cout << "Positioned Right, Pointing Up:" << std::endl;   
        _testDotLocate(fCenter-fBgSide, 0.0f,
                       fCenter+fBgSide, fBgSide,
                       fCenter+fBgSide, fSmSide,
                       fCenter-fBgSide, 0.0f);    
        
        // Pointing down from the right side
        // Class:     Boundary.XAxis
        // Test:      010
        // Position:  Right
        // Point At:  Down
        std::cout << "Positioned Right, Pointing Down:" << std::endl;   
        _testDotLocate(fCenter-fBgSide, 480.0f - fBgSide,
                       fCenter+fBgSide, 480.0f,
                       fCenter+fSmSide, 480.0f,
                       fCenter-fBgSide, 480.0f - fBgSide);  
        
                       
        return bRes;
    }
    
    
    
    
    ///////////////////////////////////
    // Boundary tests on the Y-Axis
    bool testBoundaryYAxis(void)
    {
        bool bRes = true;
        //float fCenter = MAXHEIGHT/2.0f;
        std::cout << "\n************************\n"
                  <<   "**    Y-Axis Tests    **\n"
                  <<   "************************" << std::endl;
        
        // Largest Possible square, centered
        // Class:     Boundary.YAxis
        // Test:      001
        // Position:  center
        // Point At:  center
        std::cout << "Largest possible square, centered:" << std::endl;
        _testDotLocate(0.0f, 0.0f,
                       MAXHEIGHT-1.0f, 0.0f,
                       MAXHEIGHT-1.0f, MAXHEIGHT-1.0f,
                       0.0f, MAXHEIGHT-1.0f);
        return bRes;
    }
    
    
    
    
    
    ///////////////////////////////////
    // Boundary tests on the Z-Axis
    bool testBoundaryZAxis(void)
    {
        bool bRes = true;
        float fCenter = MAXHEIGHT/2.0f;
        std::cout << "\n************************\n"
                  <<   "**    Z-Axis Tests    **\n"
                  <<   "************************" << std::endl;
        
        // Largest Possible square, centered
        // Class:     Boundary.ZAxis
        // Test:      001
        // Position:  center
        // Point At:  center
        std::cout << "Largest possible square, centered:" << std::endl;
        _testDotLocate(0.0f, 0.0f,
                       MAXHEIGHT-1.0f, 0.0f,
                       MAXHEIGHT-1.0f, MAXHEIGHT-1.0f,
                       0.0f, MAXHEIGHT-1.0f);
        
        // Smallest Possible square, centered
        // Class:     Boundary.ZAxis
        // Test:      002
        // Position:  center
        // Point At:  center
        std::cout << "Smallest possible square, centered:" << std::endl;
        _testDotLocate(fCenter-0.5f, fCenter-0.5f,
                       fCenter+0.5f, fCenter-0.5f,
                       fCenter+0.5f, fCenter+0.5f,
                       fCenter-0.5f, fCenter+0.5f);     
                                             
        // Larger than possible square, centered
        // Class:     Boundary.ZAxis
        // Test:      003
        // Position:  center
        // Point At:  center
        std::cout << "Larger than possible square, centered:" << std::endl;
        _testDotLocate(0.0f, 0.0f,
                       MAXHEIGHT, 0.0f,
                       MAXHEIGHT, MAXHEIGHT,
                       0.0f, MAXHEIGHT);
                       
        // Smaller than possible square, centered
        // Class:     Boundary.ZAxis
        // Test:      004
        // Position:  center
        // Point At:  center
        std::cout << "Smaller than possible square, centered:" << std::endl;
        _testDotLocate(fCenter-0.01f, fCenter-0.01f,
                       fCenter+0.01f, fCenter-0.01f,
                       fCenter+0.01f, fCenter+0.01f,
                       fCenter-0.01f, fCenter+0.01f);  
        return bRes;
        
        // Inverted square (dots in incorrect order
        // Class:     Boundary.ZAxis
        // Test:      005
        // Position:  center
        // Point At:  center
        std::cout << "Inverted square, centered:" << std::endl;
        _testDotLocate(fCenter+5.0f, fCenter+5.0f,
                       fCenter-5.0f, fCenter+5.0f,
                       fCenter-5.0f, fCenter-5.0f,
                       fCenter+5.0f, fCenter-5.0f);   
                       
        return bRes;
    }
    
    
  protected:    
    // Executes a test and prints the result
    void _testDotLocate(float fBLX, float fBLY,
                        float fBRX, float fBRY,
                        float fTRX, float fTRY,
                        float fTLX, float fTLY) 
    {
        Dot bl(fBLX, fBLY);
        Dot br(fBRX, fBRY);
        Dot tr(fTRX, fTRY);
        Dot tl(fTLX, fTLY);
        _ltr->locate(bl, br, tr, tl, _loc);
        _ltr->print(_loc);
    }
    
  protected:
    // Member variables
    DotLocate * _ltr;
    Location _loc;

};


// Test cases
// 5 positions
// left, right, above, below, center
// 5 point at's
//    up, left, right, down, center

// 5x5 = 25 test cases

// 3-5 depths?
//    max near, bigger, exact size, smaller, max far


// tests the position information
#ifdef _TEST_DOT_LOCATE_

int main(int argc, char * const argv[]) 
{
    TestDotLocate tdl;
    tdl.testAll();
    return 0;
}

#endif
